<?php
/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
// Chat Server
// Project: molten-chat
// Developed by: Matthew Oltendorf
// Version: b2.1
// Updated on: June 04th, 2009
// Copyright (c) 2008-2009 Matthew Oltendorf
// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */

// PHP: Hypertext Preprocessor Document

/*
	Unfinished Items:
		1.
		2.
		3.
		4.
		5.
*/

/*
	Known Issues:
		1.
		2.
		3.
		4.
		5.
*/

if (
	!defined ('molten_chat')
)
	{
		die ('Unauthorised Access.');
	}

/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
// Name: molten_chat_functions
// Type: Singleton.
// Title: MoltX Chat Function Object.
// Description: All of these functions can be called by users in chat rooms that have permission to do so.
// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
final class molten_chat_functions
	{
		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: __construct
		// Title: Class construction.
		// Variables: None.
		// Description: Disabled.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		private function __construct ()
			{
				// No further actions required.
				return false;
			}
		
		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: __destruct
		// Title: Class destruction.
		// Variables: None.
		// Description: Disabled.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		private function __destruct ()
			{
				// No further actions required.
				return false;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: announce
		// Title: Generate an announcement message..
		// Variables: $user, $arguments
		//	1.	$user: The user that called this function. Not used in this function.
		//	2.	$arguments: The array of arguments this function accepts.
		// Description: Send a announcement message. Also an example function for future additions.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		public static function announce ($user, $arguments)
			{
				// Bad, we should not rely on the phpBB 3 permissions system.
				try
					{
						global $user;

						if (
							$user -> data ['user_type'] != USER_FOUNDER
						)
							{
								return false;
							}
					}
				catch (Exception $exception)
					{
						// Swallow error (for use in standalone module).
					}

				// All arguments are sent in a single array, so we must manually check for their existence.
				try
					{
						// We accept null here, so this is the best way to check for a variable that is set to null: try-catch blocks.

						/*
						 * Variables in the arguments array can be passed as any of the following types:
						 * 1. Boolean
						 * 2. Float
						 * 3. Integer
						 * 4. Null
						 * 5. String
						 *
						 * Variables can also be an array containing any of those five types.
						 */

						// This is our magic "test if it's set."
						$message = $arguments ['message'];
					}
				catch (Exception $exception)
					{
						// The message variable does not exist. Return false to make the message they sent display.
						return false;
					}
				
				// Update the announcement variable in the chat server.
				molten_chat_server :: $room ['data'] ['announcement'] = molten_chat_server :: to_string ($message);

				$file = molten_chat_server :: $room ['files'] ['data'];

				$export = var_export (molten_chat_server :: $room ['data'], true);

				$export = sprintf (molten_chat_server :: $formatting ['data'], $export);

				// Open and/or create file.
				$pointer = fopen ($file, 'a+');

				// Acquire lock without blocking.
				while (!flock ($pointer, LOCK_EX | LOCK_NB))
					{
						// Generate a random number.
						$random = mt_rand (0, 250);

						// Sleep for 0.000 to 0.250 seconds. seconds.
						usleep (1000 * $random);
					}

				ftruncate ($pointer, 0);

				// Write data contents to new room descriptor.
				fwrite ($pointer, $export);
				
				// Close the file.
				flock ($pointer, LOCK_UN);
				fclose ($pointer);

				// Send a message to the system.
				/*
				 * The first parameter is the message itself.
				 * The second parameter is the user, we set this to false to make it a system message.
				 * The third parameter is whether or not the message is raw input from the outside world.
				 *		We set it to false because even though this is input, it was already cleaned.
				 * The fourth parameter is whether or not to call a slash command if the message begins with a slash.
				 *		You definitely should set this to false because if you don't, infinite loops can occur!
				 * The fifth parameter is whether or not this message is linked.
				 *		We have left it empty because it is false by default.
				 *
				 * Remember: The send function uses the internal function to_string;
				 *		to_string casts booleans, null values, and objects to their textual representation.
				 */
				molten_chat_server :: send (molten_chat_server :: $language ['new_announcement'] . ': ' . molten_chat_server :: to_string ($message), false, false, false);

				// True means that the message the user sent is not displayed. False means it is displayed.
				return true;
			}
		
		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: system
		// Title: Send system message.
		// Variables: $user, $arguments
		//	1.	$user: The user that called this function. Not used in this function.
		//	2.	$arguments: The array of arguments this function accepts.
		// Description: Send a system message. Also an example function for future additions.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		public static function system ($user, $arguments)
			{
				// Bad, we should not rely on the phpBB 3 permissions system.
				try
					{
						global $user;

						if (
							$user -> data ['user_type'] != USER_FOUNDER
						)
							{
								return false;
							}
					}
				catch (Exception $exception)
					{
						// Swallow error (for use in standalone module).
					}

				// All arguments are sent in a single array, so we must manually check for their existence.
				try
					{
						// We accept null here, so this is the best way to check for a variable that is set to null: try-catch blocks.
						
						/*
						 * Variables in the arguments array can be passed as any of the following types:
						 * 1. Boolean
						 * 2. Float
						 * 3. Integer
						 * 4. Null
						 * 5. String
						 *
						 * Variables can also be an array containing any of those five types.
						 */

						// We check if it is an array. If not, we cast it to an array.
						$messages = is_array ($arguments ['message']) ?
							$arguments ['message'] :
							array ($arguments ['message']);
					}
				catch (Exception $exception)
					{
						// The message variable does not exist. Return false to make the message they sent display.
						return false;
					}

				// This is the ultimate purpose of this function: To send each message received as a system message.
				foreach ($messages as $message)
					{
						// Send a message to the system.
						/*
						 * The first parameter is the message itself.
						 * The second parameter is the user, we set this to false to make it a system message.
						 * The third parameter is whether or not the message is raw input from the outside world.
						 *		We set it to false because even though this is input, it was already cleaned.
						 * The fourth parameter is whether or not to call a slash command if the message begins with a slash.
						 *		You definitely should set this to false because if you don't, infinite loops can occur!
						 * The fifth parameter is whether or not this message is linked.
						 *		We have left it empty because it is false by default.
						 *
						 * Remember: The send function uses the internal function to_string;
						 *		to_string casts booleans, null values, and objects to their textual representation.
						 */
						molten_chat_server :: send ($message, false, false, false);
					}

				// Check if any messages were sent.
				// But, we shouldn't be here in the first place if no messages were sent;
				//		The try-catch block would have ended it if there were none.
				$success = (boolean) count ($messages);

				// True means that the message the user sent is not displayed. False means it is displayed.
				return $success;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: link
		// Title: Link a message.
		// Variables: $user, $arguments
		//	1.	$user: The user that called this function. Not used in this function.
		//	2.	$arguments: The array of arguments this function accepts.
		// Description: Make an entire message linked to a specific page. Also an example function for future additions.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		public static function link ($user, $arguments)
			{
				if (
					$user !== false
				)
					{
						// Fix.
						$local_user = $user;

						// Bad, we should not rely on the phpBB 3 permissions system.
						try
							{
								global $user;

								if (
									$user -> data ['user_type'] != USER_FOUNDER
								)
									{
										// Force local and system to be false.
										$arguments ['local'] = false;
										$arguments ['system'] = false;
									}
								else
									{
										if (
											!empty ($arguments ['system'])
										)
											{
												$local_user = false;
											}
									}
							}
						catch (Exception $exception)
							{
								// Swallow error (for use in standalone module).
							}

						// Fix.
						$user = $local_user;
					}

				// Convert to boolean without throwing an exception.
				$local = !empty ($arguments ['local']);
				$system = !empty ($arguments ['system']);

				// All future variables must exist, otherwise we just silently fail.
				try
					{
						/*
						 * Variables in the arguments array can be passed as any of the following types:
						 * 1. Boolean
						 * 2. Float
						 * 3. Integer
						 * 4. Null
						 * 5. String
						 *
						 * Variables can also be an array containing any of those five types.
						 */

						// Either "url" or "uri" must exist. If neither do, jump to the catch block.
						$uri = isset ($arguments ['url']) ?
							$arguments ['url'] :
							$arguments ['uri'];

						// If message does not exist, we simply use the uri.
						$message = isset ($arguments ['message']) ?
							$arguments ['message'] :
							$uri;

						// Send a message to the system.
						/*
						 * The first parameter is the message itself.
						 * The second parameter is the user, we set this to false to make it a system message.
						 * The third parameter is whether or not the message is raw input from the outside world.
						 *		We set it to false because even though this is input, it was already cleaned.
						 * The fourth parameter is whether or not to call a slash command if the message begins with a slash.
						 *		You definitely should set this to false because if you don't, infinite loops can occur!
						 * The fifth parameter is whether or not this message is linked.
						 *
						 * Remember: The send function uses the internal function to_string;
						 *		to_string casts booleans, null values, and objects to their textual representation.
						 */
						molten_chat_server :: send ($message, (!$system ? $user : false), false, false, array ('local' => $local, 'uri' => $uri));

						return true;
					}
				catch (Exception $exception)
					{
						// Swallow error, we just return false at the end.
					}

				// True means that the message the user sent is not displayed. False means it is displayed.
				return false;
			}
	}
?>